﻿using System;
using System.Drawing;
using breakoutsharp.utility;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace breakoutsharp.visual.gameobject
{
	public class Ball : IScreenObject
	{
		protected PointF direction;
		protected PointF location;
		protected SizeF size;
		protected bool visible;
		protected int speed;
		protected int blocksHit = 0;
		protected int blocksKilled = 0;
		protected int blocksDamaged = 0;
		protected bool alive = true;
		protected bool disposed = false;
		protected Color ballColor = Color.AliceBlue;

		public bool HasBeenCorrolated
		{
			get;
			set;
		}

		protected static VertexBuffer ballVertex;
		protected static Texture ballTexture;
		protected static CustomVertex.PositionTextured[] ballVertices;

		public Ball(PointF location, PointF direction)
			: this(location, direction, new SizeF(10, 10))
		{
		}

		public Ball(PointF location, PointF direction, SizeF size)
		{
			this.direction = direction;

			/* Normalize direction */
			double len = Math.Sqrt(direction.X * direction.X + direction.Y * direction.Y);
			direction.Y /= (float)len;
			direction.X /= (float)len;

			this.location = location;
			this.size = size;


		}

		#region IScreenObject Members

		public void Draw(Device device)
		{
			if (ballVertex == null)
			{
				/* Following was to be used if textures was wanted instead of plain colouring */
				CustomVertex.PositionTextured[] verts = new CustomVertex.PositionTextured[6];
				verts[0] = new CustomVertex.PositionTextured(new Vector3(0, 0, 0), 0, 0);
				verts[1] = new CustomVertex.PositionTextured(new Vector3(0, -10, 0), 0, 1);
				verts[2] = new CustomVertex.PositionTextured(new Vector3(10, 0, 0), 1, 0);
				verts[3] = new CustomVertex.PositionTextured(new Vector3(0, -10, 0), 0, 1);
				verts[4] = new CustomVertex.PositionTextured(new Vector3(10, -10, 0), 1, 1);
				verts[5] = new CustomVertex.PositionTextured(new Vector3(10, 0, 0), 1, 0);

				/* Load texture */
				Ball.ballTexture = new Texture(device, new Bitmap(@"data\gfx\Untitled-1.png"), 0, Pool.Managed);
				//blockText = TextureLoader.FromFile(device, @"data\gfx\blockTexture.bmp");

				Ball.ballVertex = new VertexBuffer(typeof(CustomVertex.PositionTextured), verts.Length, device, Usage.WriteOnly | Usage.Dynamic, CustomVertex.PositionTextured.Format, Pool.Default);
				Ball.ballVertex.SetData(verts, 0, LockFlags.None);

				/* SAVE VERTICES FOR POTENTIAL LATER USE */
				Ball.ballVertices = verts;


				//CustomVertex.PositionColored[] ballVerts = new CustomVertex.PositionColored[5];
				//ballVerts[0] = new CustomVertex.PositionColored(new Vector3(0, 10 * -1, 0), ballColor.ToArgb());
				//ballVerts[1] = new CustomVertex.PositionColored(new Vector3(0, 0, 0), ballColor.ToArgb());
				//ballVerts[2] = new CustomVertex.PositionColored(new Vector3(10, 10 * -1, 0), ballColor.ToArgb());
				//ballVerts[3] = new CustomVertex.PositionColored(new Vector3(10, 0, 0), ballColor.ToArgb());

				//Ball.ballVertex = new VertexBuffer(typeof(CustomVertex.PositionColored), ballVerts.Length, device, Usage.WriteOnly | Usage.Dynamic, CustomVertex.PositionColored.Format, Pool.Default);
				//Ball.ballVertex.SetData(ballVerts, 0, LockFlags.None);
			}

			/* Balls vertexes is the ones to be drawn */
			device.SetStreamSource(0, ballVertex, 0);
			device.SetTexture(0, Ball.ballTexture);

			device.Transform.World = Matrix.Translation(this.Location.X, -1 * this.Location.Y, 0f);
			device.DrawPrimitives(PrimitiveType.TriangleList, 0, 2);
		}

		public RectangleF GetRectF
		{
			get
			{
				return new RectangleF(this.location, this.size);
			}

		}

		public Rectangle GetRect
		{
			get
			{
				return new Rectangle((int)location.X, (int)location.Y, (int)size.Width, (int)size.Height);
			}
		}


		public PointF Location
		{
			get
			{
				return this.location;
			}
			set
			{
				this.location = value;
			}
		}

		public SizeF Size
		{
			get
			{
				return this.size;
			}
			set
			{
				this.size = value;
			}
		}

		public bool Visible
		{
			get
			{
				return visible;
			}
			set
			{
				visible = value;
			}
		}

		#endregion

		public bool Alive
		{
			get
			{
				return this.alive;
			}
			set
			{
				this.alive = value;
			}
		}

		public int BlockDamaged
		{
			get
			{
				return this.blocksDamaged;
			}
			set
			{
				this.blocksDamaged = value;
			}
		}

		public int BlocksHit
		{
			get
			{
				return this.blocksHit;
			}
			set
			{
				this.blocksHit = value;
			}
		}

		public int BlocksKilled
		{
			get
			{
				return this.blocksKilled;
			}
			set
			{
				this.blocksKilled = value;
			}
		}

		public PointF Direction
		{
			get
			{
				return this.direction;
			}
			set
			{
				this.direction = value;
			}
		}

		public int Speed
		{
			get
			{
				return this.speed;
			}
			set
			{
				this.speed = value;
			}
		}

		public void InvertHorizontal()
		{
			this.direction = new PointF(this.direction.X * -1, this.direction.Y);
		}

		public void InvertVertical()
		{
			this.direction = new PointF(this.direction.X, this.direction.Y * -1);
		}

		public void InvertBoth()
		{
			InvertHorizontal();
			InvertVertical();
		}


		public bool IsGoingRight
		{
			get
			{
				if (direction.X > 0)
				{
					return true;
				}

				return false;
			}
		}

		public bool IsGoingLeft
		{
			get
			{
				if (direction.X < 0)
				{
					return true;
				}

				return false;
			}
		}

		public bool IsGoingUp
		{
			get
			{
				if (direction.Y < 0)
				{
					return true;
				}

				return false;
			}
		}

		public bool IsGoingDown
		{
			get
			{
				if (direction.Y > 0)
				{
					return true;
				}

				return false;
			}
		}
	}
}
